/**
 * 
 */
package cn.springsoter.core.security.handler;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import cn.hutool.core.util.CharsetUtil;
import cn.springsoter.core.security.strategy.impl.ReadAESKeyDefaultStrategy;
import cn.springsoter.core.security.strategy.impl.ReadAESKeyStoreStrategy;
import cn.springsoter.core.tool.utils.AESUtil;

/**
 * AES加/解密字段处理类
 * 
 * mybatis执行顺序：Interceptor -> TypeHandler
 * 
 * @author kevin
 *
 */
@Component
public class AESEncryptHandler<T> extends BaseTypeHandler<T> {

	@Autowired
	private ReadAESKeyDefaultStrategy readAESKeyDefaultStrategy;
	@Autowired
	private ReadAESKeyStoreStrategy readAESKeyStoreStrategy;
	
	@Override
	public void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {
		String value = (String)parameter;
		String key = null;
		try {
			key = StringUtils.isBlank(readAESKeyStoreStrategy.readKey()) ? readAESKeyDefaultStrategy.readKey() : readAESKeyStoreStrategy.readKey();
		} catch (Exception e1) {
		}
		if(StringUtils.isNotBlank(key)) {
			try {
				value = AESUtil.encryptByECBBase64(key.getBytes(CharsetUtil.CHARSET_UTF_8), value.getBytes(CharsetUtil.CHARSET_UTF_8));
			} catch (Exception e) {}
		}
		ps.setString(i, value);
	}

	@Override
	public T getNullableResult(ResultSet rs, String columnName) throws SQLException {
		String columnValue = rs.getString(columnName);
		return decryptValue(columnValue);
	}

	@Override
	public T getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
		String columnValue = rs.getString(columnIndex);
		return decryptValue(columnValue);
	}

	@Override
	public T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
		String columnValue = cs.getString(columnIndex);
		return decryptValue(columnValue);
	}

	/**
	 * 解密
	 * 
	 * @param columnValue
	 * @return
	 */
	private T decryptValue(String columnValue) {
		String key = null;
		try {
			key = StringUtils.isBlank(readAESKeyStoreStrategy.readKey()) ? readAESKeyDefaultStrategy.readKey() : readAESKeyStoreStrategy.readKey();
		} catch (Exception e1) {
		}
		
		if(StringUtils.isNotBlank(key)) {
			try {
				columnValue = AESUtil.decryptByECBString(key.getBytes(CharsetUtil.CHARSET_UTF_8), columnValue);
			} catch (Exception e) {}
		}
        //有一些可能是空字符
        return (T) columnValue;
	}
}
